/**
 * 
 */
package edu.gtcfla.km.appmodules.service.impl;

import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.springframework.beans.factory.annotation.Autowired;
import org.vsg.biz.BusinessEntityFactory;
import org.vsg.biz.BusinessOperationException;

import edu.gtcfla.km.Category;
import edu.gtcfla.km.appmodules.service.CategoryService;
import edu.gtcfla.km.appmodules.vo.CategoryFormVO;
import edu.gtcfla.km.appmodules.vo.CategoryNodeVO;
import edu.gtcfla.km.security.api.SubjectManager;

/**
 * @author vison
 *
 */
public class CategoryServiceI implements CategoryService {

	@Autowired(required=false)
	private edu.gtcfla.km.repositories.CategoryRepo<Category,String> categoryRepo;

	
	@Autowired(required = false)
	private SubjectManager subjectManager;		

	@Autowired(required=false)
	private BusinessEntityFactory entityFactory;		
	
	public edu.gtcfla.km.repositories.CategoryRepo<Category, String> getCategoryRepo() {
		return categoryRepo;
	}

	public void setCategoryRepo(edu.gtcfla.km.repositories.CategoryRepo<Category, String> categoryRepo) {
		this.categoryRepo = categoryRepo;
	}

	/* (non-Javadoc)
	 * @see edu.gtclfla.km.appmodules.service.CategoryService#getTreeForAllCategories()
	 */
	@Override
	public Set<CategoryNodeVO> getTreeForAllCategories()
			throws BusinessOperationException {
		// --- handle main lobic ---
		Map<String , Category>  allMap =  categoryRepo.findAllMap();
		
		Map<String , CategoryNodeVO> outputTreeNode = new LinkedHashMap<String , CategoryNodeVO>();
		
		Set<Category> cateWithParentSet = new LinkedHashSet<Category>();
		
		for ( Category cate : allMap.values() ) {
			
			CategoryNodeVO tree = new CategoryNodeVO();
			tree.setId( cate.getId() );
			tree.setText( cate.getName() );
			tree.setLeaf(true);

			if (cate.getParent() != null) {
				cateWithParentSet.add( cate );
			}
			
			outputTreeNode.put( cate.getId() , tree);
		}


		Set<String> dupicateNodeIds = new LinkedHashSet<String>();
		
		for (Category disWithPar : cateWithParentSet) {
			String parentId = disWithPar.getParent().getId();
			
			CategoryNodeVO treeNode = outputTreeNode.get( parentId );
			Collection<CategoryNodeVO> children = treeNode.getChildren();
			if ( children == null) {
				children = new Vector<CategoryNodeVO>();
				treeNode.setLeaf(false);
			}
			
			
			// --- get child node 
			CategoryNodeVO child = outputTreeNode.get( disWithPar.getId() );
			
			dupicateNodeIds.add( child.getId() );
			
			children.add( child );
			
			treeNode.setChildren( children );

		}

		for (String nodeId : dupicateNodeIds) {
			outputTreeNode.remove( nodeId );
		}
		
		Set<CategoryNodeVO> result = new LinkedHashSet<CategoryNodeVO>();
		result.addAll( outputTreeNode.values() );
		
		return result;


	}

	/* (non-Javadoc)
	 * @see edu.gtclfla.km.appmodules.service.CategoryService#addCategory(edu.gtclfla.km.appmodules.vo.CategoryFormVO)
	 */
	@Override
	public void addCategory(CategoryFormVO formView)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		Category entity = formView.getCategory();
		
		// --- set parent ---
		String parentId = formView.getParentId();
		if (parentId != null && !parentId.trim().equals("") && !parentId.trim().equals("root")) {
			Category parent = categoryRepo.findOne( parentId );
			entity.setParent( parent );
		} else {
			entity.setParent(null);

		}

		
		String currAccountId = subjectManager.getCurrentAccountId();
		Calendar cale = Calendar.getInstance();
		entity.setCreatedUserId(currAccountId );
		entity.setCreatedDate( cale.getTime() );
	
		categoryRepo.save( entity );		

	}

	/* (non-Javadoc)
	 * @see edu.gtclfla.km.appmodules.service.CategoryService#updateCategory(edu.gtclfla.km.appmodules.vo.CategoryFormVO)
	 */
	@Override
	public void updateCategory(CategoryFormVO formVO)
			throws BusinessOperationException {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see edu.gtclfla.km.appmodules.service.CategoryService#updateAll(java.util.Set)
	 */
	@Override
	public void updateAll(Set<CategoryFormVO> allCate)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		Set<String> ids = new LinkedHashSet<String>(); 
		for (CategoryFormVO cateForm : allCate) {
			ids.add( cateForm.getId() );
			if (cateForm.getParentId() != null && !cateForm.getParentId().equals("")) {
				ids.add( cateForm.getParentId() );
			}
		}

		Map<String, Category> cateMap = categoryRepo.findAllByIds( ids );

		Set<Category> updatingCates = new LinkedHashSet<Category>();
		
		// --- update all menu ---
		for (CategoryFormVO form : allCate) {
			Category updateingCate = cateMap.get(form.getId());
			
			if (form.getName() != null && !form.getName().equals(updateingCate.getName())) {
				updateingCate.setName( form.getName() );
			}

			
			if (form.getParentId() != null) {
				// --- update parent id ---
				Category parent = cateMap.get( form.getParentId() );
				updateingCate.setParent( parent );

			}
			
			updatingCates.add(updateingCate);
		}
		
		categoryRepo.updateAll( updatingCates );
			

	}

	/* (non-Javadoc)
	 * @see edu.gtclfla.km.appmodules.service.CategoryService#deleteCategoryIds(java.lang.String[])
	 */
	@Override
	public void deleteCategoryIds(String[] ids)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
		for (String id : ids) {
			Category cate = entityFactory.create( Category.class );
			cate.setId( id );

			categoryRepo.deleteFully(cate);

		}			

	}

}
